//
// Created by Admin on 2024/3/27.
//
#include <stdlib.h>
//#include <stddef.h>
#include <stdbool.h>
#include <wchar.h>
#include <string.h>
//#include <unicode/uclean.h>
//#include <unicode/ustring.h>
#include "utils/utils.h"

int test123() {
    return 123;
}

//// 计算 utf8 字符串的长度
//int utf8_isvalid(const char *str)
//{
//    UErrorCode status = U_ZERO_ERROR; // 初始化错误码
//
//    UChar ustr[100]; // 用于存储转换后的 UTF-16 编码的字符串
//    int32_t ustr_len;
//
//    // 将 UTF-8 编码的字符串转换为 UTF-16 编码的字符串
//    u_strFromUTF8WithSub(ustr, sizeof(ustr)/sizeof(ustr[0]), &ustr_len, 1, -1, 0xFFFD, &status，1);
//
//    // 使用 UTF_IS_VALID 宏检查 UTF-16 编码的字符串是否合法
//    int isValid = true;
//    for (int i = 0; i < ustr_len; ++i) {
//        if (!UTF_IS_VALID(ustr[i])) {
//            isValid = false;
//            break;
//        }
//    }
//
//    // 输出检查结果
//    if (isValid) {
//        printf("String is valid UTF-8\n");
//    } else {
//        printf("String is not valid UTF-8\n");
//    }
//
//    return 0;
//}

// 计算 utf8 字符串的长度
int utf8_strlen(const char *str)
{
    int len = 0;
    int i = 0;

    while (str[i] != '\0') {
        if ((str[i] & 0x80) == 0) {
            // 1个字节
            len++;
            i++;
        } else if ((str[i] & 0xe0) == 0xc0) {
            // 2个字节
            len++;
            i += 2;
        } else if ((str[i] & 0xf0) == 0xe0) {
            // 3个字节
            len++;
            i += 3;
        } else if ((str[i] & 0xf8) == 0xf0) {
            // 4个字节
            len++;
            i += 4;
        } else {
            // 非法UTF-8字符
            break;
        }
    }

    return len;
}

// 获取 utf8 的字符串中的某个字符
char *utf8_substr(const char *str, int start, int length)
{
    char *empty = malloc(1);
    empty[0] = '\0';

    if (length < 1) {
        return empty;
    }

    char *sub = malloc(length * MB_CUR_MAX + 1);
    int i = 0;
    int len = 0;
    int count = 0;

    while (str[i] != '\0') {
        if (i < start) {
            i++;
            continue;
        }

        if ((str[i] & 0x80) == 0) {
            // 1个字节
            sub[len] = str[i];

            i++;
            len++;
            count++;
        } else if ((str[i] & 0xe0) == 0xc0) {
            // 2个字节
            sub[len] = str[i];
            sub[len + 1] = str[i + 1];

            i += 2;
            len += 2;
            count++;
        } else if ((str[i] & 0xf0) == 0xe0) {
            // 3个字节
            sub[len] = str[i];
            sub[len + 1] = str[i + 1];
            sub[len + 2] = str[i + 2];

            i += 3;
            len += 3;
            count++;
        } else if ((str[i] & 0xf8) == 0xf0) {
            // 4个字节
            sub[len] = str[i];
            sub[len + 1] = str[i + 1];
            sub[len + 2] = str[i + 2];
            sub[len + 3] = str[i + 3];

            i += 4;
            len += 4;
            count++;
        } else {
            // 非法UTF-8字符
            break;
        }

        if (count == length) {
            break;
        }
    }

    len++;
    sub[len] = '\0';
    // memcpy(sub, str + start, count);

    return sub;
}

bool utf8_is_valid(const char *str) {
    while (*str != '\0') {
        if ((*str & 0x80) == 0) {
            // 单字节字符
            str++;
        } else if ((*str & 0xE0) == 0xC0) {
            // 双字节字符
            if ((*(str + 1) & 0xC0) != 0x80) {
                return false;
            }
            str += 2;
        } else if ((*str & 0xF0) == 0xE0) {
            // 三字节字符
            if ((*(str + 1) & 0xC0) != 0x80 || (*(str + 2) & 0xC0) != 0x80) {
                return false;
            }
            str += 3;
        } else if ((*str & 0xF8) == 0xF0) {
            // 四字节字符
            if ((*(str + 1) & 0xC0) != 0x80 || (*(str + 2) & 0xC0) != 0x80 || (*(str + 3) & 0xC0) != 0x80) {
                return false;
            }
            str += 4;
        } else {
            // 不符合 UTF-8 编码规则的字节
            return false;
        }
    }
    return true;
}

// 获取 utf8 的字符串中的某个字符
char *utf8_get_char(const char *str, int index)
{
    int i = 0;
    int count = 0;
    int len = 0;

    while (str[i] != '\0') {
        if ((str[i] & 0x80) == 0) {
            // 1个字节
            if (count == index) {
                char *p = malloc(1);
                p[0] = str[i];
                return p;
            }
            count++;
            i++;
        } else if ((str[i] & 0xe0) == 0xc0) {
            // 2个字节
            if (count == index) {
                char *p = malloc(2);
                p[0] = str[i];
                p[1] = str[i + 1];
                return p;
            }
            count++;
            i += 2;
        } else if ((str[i] & 0xf0) == 0xe0) {
            // 3个字节
            if (count == index) {
                char *p = malloc(3);
                p[0] = str[i];
                p[1] = str[i + 1];
                p[2] = str[i + 2];
                return p;
            }
            count++;
            i += 3;
        } else if ((str[i] & 0xf8) == 0xf0) {
            // 4个字节
            if (count == index) {
                char *p = malloc(4);
                p[0] = str[i];
                p[1] = str[i + 1];
                p[2] = str[i + 2];
                p[3] = str[i + 3];
                return p;
            }
            count++;
            i += 4;
        } else {
            // 非法UTF-8字符
            break;
        }
    }

    return NULL;
}


//char *utf8_get_char2(const char *str)
//{
//    // 保存转换状态的结构
//    mbstate_t state;
//
//    // 初始化转换状态
//    memset(&state, 0, sizeof(state));
//
//    // 获取多字节字符串的长度
//    size_t str_len = strlen(str);
//
//    // 计算宽字符字符串的长度
//    size_t wc_string_len = mbsrtowcs(NULL, &str, str_len, &state);
//    if (wc_string_len == (size_t)-1) {
//        perror("mbsrtowcs failed");
//    }
//
//    // 分配足够的空间来存储宽字符字符串
//    wchar_t wc_string[wc_string_len + 1];
//
//    // 重置转换状态
//    memset(&state, 0, sizeof(state));
//    mb_string = "你好，世界！"; // 重新设置多字节字符串的指针
//
//    // 进行零拷贝转换
//    if (mbsrtowcs(wc_string, &mb_string, wc_string_len, &state) == (size_t)-1) {
//        perror("mbsrtowcs failed");
//        return 1;
//    }
//}